home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 3: Developer Tools / Linux Cubed Series 3 - Developer Tools.iso / devel / lang / lisp / gcl-1.000 / gcl-1 / gcl-1.0 / c / saveaix3.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-05-07  |  7.3 KB  |  284 lines

  1. /*
  2.  Copyright (C) 1994 M. Hagiya, W. Schelter, T. Yuasa
  3.  
  4. This file is part of GNU Common Lisp, herein referred to as GCL
  5.  
  6. GCL is free software; you can redistribute it and/or modify it under
  7. the terms of the GNU LIBRARY GENERAL PUBLIC LICENSE as published by
  8. the Free Software Foundation; either version 2, or (at your option)
  9. any later version.
  10.  
  11. GCL is distributed in the hope that it will be useful, but WITHOUT
  12. ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13. FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public 
  14. License for more details.
  15.  
  16. You should have received a copy of the GNU Library General Public License 
  17. along with GCL; see the file COPYING.  If not, write to the Free Software
  18. Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  19.  
  20.  
  21. (c) Copyright William F. Schelter.
  22.   
  23. */
  24. /*
  25.     unixsave.c
  26. */
  27. #ifndef UNIX
  28. #include "include.h"
  29. #endif
  30.  
  31. #include <fcntl.h>
  32. #include <filehdr.h>
  33. #include <aouthdr.h>
  34. #include <scnhdr.h>
  35. filecpy(to, from, n)
  36. FILE *to, *from;
  37. register int n;
  38. {
  39.     char buffer[BUFSIZ];
  40.     for (;;)
  41.         if (n > BUFSIZ) {
  42.             fread(buffer, BUFSIZ, 1, from);
  43.             fwrite(buffer, BUFSIZ, 1, to);
  44.             n -= BUFSIZ;
  45.         } 
  46.         else if (n > 0) {
  47.             fread(buffer, 1, n, from);
  48.             fwrite(buffer, 1, n, to);
  49.             break;
  50.         } 
  51.         else
  52.             break;
  53. }
  54. #include <sys/ldr.h>
  55. #include <loader.h>
  56. char *__start;
  57. memory_save(original_file, save_file)
  58. char *original_file, *save_file;
  59. {     /*   MEM_SAVE_LOCALS; */ 
  60.     struct filehdr Eheader;
  61.     struct aouthdr header;
  62.     struct scnhdr  shdrs[15];
  63.     int stsize;
  64.     int textsize=0;
  65.     int after_data;
  66.     int orig_data_scnptr;
  67.     int orig_debug_scnptr;
  68.  
  69.     char *data_begin, *data_end;
  70.     int original_data;
  71.     FILE *original, *save;
  72.     register int n;
  73.     register char *p;
  74.     extern char *sbrk();
  75.     extern char stdin_buf[BUFSIZ], stdout_buf[BUFSIZ];
  76.     fclose(stdin);
  77.     original = fopen(original_file, "r");
  78.     if (stdin != original || original->_file != 0) {
  79.       fprintf(stderr, "Can't open the original file.\n");
  80.       exit(1);
  81.     }
  82.     setbuf(original, stdin_buf);
  83.     fclose(stdout);
  84.     unlink(save_file);
  85.     n = open(save_file, O_CREAT|O_WRONLY, 0777);
  86.     if (n != 1 || (save = fdopen(n, "w")) != stdout) {
  87.       fprintf(stderr, "Can't open the save file.\n");
  88.       exit(1);
  89.     }
  90.     setbuf(save, stdout_buf);
  91.     /*    READ_HEADER; */
  92.     fread(&Eheader, sizeof(Eheader), 1, original);
  93.     fread(&header, sizeof(header), 1, original);
  94.     data_begin= 0x20000800;
  95.     {
  96.       char buf[500];
  97.       struct ld_info * ld;
  98.       loadquery(L_GETINFO,buf,sizeof(buf));
  99.       ld = (struct ld_info *)buf;
  100.       data_begin = ld->ldinfo_dataorg ;
  101.     }
  102.  
  103.     /*     header.data_start = data_begin; */
  104.  
  105.     data_end = core_end;
  106.     original_data = header.dsize;
  107.     header.dsize = data_end - data_begin;
  108.     header.bsize = 0;
  109.     {
  110.       int j,i = Eheader.f_nscns;
  111.       int diff;
  112.       fread(shdrs +1 ,i,sizeof(struct scnhdr),original);
  113.       orig_data_scnptr = shdrs[header.o_sndata].s_scnptr;
  114.       orig_debug_scnptr = shdrs[8].s_scnptr;
  115.       diff = header.a_data - original_data
  116.     - shdrs[header.o_snbss + 1].s_size;
  117.       after_data = shdrs[header.o_snbss +2].s_scnptr;
  118.       Eheader.f_symptr += diff;
  119.       fwrite(&Eheader, sizeof(Eheader), 1, save);
  120.       fwrite(&header, sizeof(header), 1, save);
  121.       shdrs[header.o_snbss ].s_size = 0;
  122.       shdrs[header.o_snbss +1 ].s_size = 0;
  123.       /* ex**pect no more than 15 sections, and pad after data */
  124.       if (strcmp(".pad",shdrs[header.o_snbss + 1].s_name)
  125.       || i >= 15)
  126.     perror("unexpected format of object file");
  127.       shdrs[header.o_sndata ].s_size = header.a_data;
  128.       /*       shdrs[header.o_sndata].s_paddr = data_begin;
  129.            shdrs[header.o_sndata].s_vaddr = data_begin;
  130.            */
  131.       for (j=1; j<= i; j++)
  132. #define ADJUST(x) if(x) (x) = (x) + diff                       
  133.     {
  134.       ADJUST(shdrs[j].s_lnnoptr);
  135.       ADJUST(shdrs[j].s_relptr);
  136.     }
  137.       for (j= header.o_sndata +1 ; j<= i; j++)
  138.     {
  139.       ADJUST(shdrs[j].s_scnptr);
  140.       ADJUST(shdrs[j].s_vaddr);
  141.       ADJUST(shdrs[j].s_paddr);
  142.     }
  143.       fwrite(shdrs +1  ,i,sizeof(struct scnhdr),save);
  144.  
  145.  
  146.       /*    FILECPY_HEADER; */
  147.       filecpy(save, original,
  148.           shdrs[header.o_sndata].s_scnptr
  149.           - sizeof(header)-sizeof(Eheader) - i*sizeof(struct scnhdr));
  150.  
  151.       j= ftell(save);
  152.       j= ftell(original);
  153.       for (n = header.a_data, p = data_begin;  ;  n -= BUFSIZ, p += BUFSIZ)
  154.     if (n > BUFSIZ)
  155.       fwrite(p, BUFSIZ, 1, save);
  156.     else if (n > 0) {
  157.       fwrite(p, 1, n, save);
  158.       break;
  159.     } 
  160.     else
  161.       break;
  162.       fseek(original, original_data, 1);
  163.       fseek(original, after_data, 0);
  164.  
  165.       /* now positioned at the loader section */
  166.       {
  167.     struct ldhdr *ldheader;
  168.     struct ldrel * ldreloc_info,*p;
  169.     char *space;
  170.     space = (char *)  sbrk(shdrs[header.o_snloader].s_size + 0x2000);
  171.     ldheader =  (struct ldhdr *) space;
  172.     fread(space,1,shdrs[header.o_snloader].s_size,original);
  173.     ldreloc_info = (struct ldrel *)
  174.       (space + sizeof(struct ldhdr) + LDSYMSZ * ldheader->l_nsyms);
  175.     i =  sizeof(struct ldhdr) + LDSYMSZ * (ldheader->l_nsyms);
  176.     for(p=ldreloc_info,i=0;  i< ldheader->l_nreloc ; i++,p++)
  177.       { 
  178.         if (p->l_rsecnm == header.o_snbss)
  179.           (p->l_rsecnm = header.o_sndata);
  180.         if (p->l_symndx == 2) /* make bss be data */
  181.           (p->l_symndx = 1);
  182.       }
  183.     /*         p->l_vaddr += data_begin; */
  184.     fwrite(ldheader, 1, shdrs[header.o_snloader].s_size,save);
  185.     /* unrelocate */
  186.     {
  187.       int j1 = ftell(save);
  188.       int j2= ftell(original);
  189.       int off=0;
  190.       fseek(original,orig_data_scnptr,0);
  191.       fseek(save,shdrs[header.o_sndata].s_scnptr,0);
  192.       for(p=ldreloc_info,i=0;  i< ldheader->l_nreloc ; i++,p++)
  193.         if (p->l_rsecnm == header.o_sndata)
  194.           {
  195.         int x,pos1,y;
  196.         int d = p->l_vaddr - off;
  197.         if (d)
  198.           {
  199.             fseek(save,d,1);
  200.             fseek(original,d,1);
  201.             off += d;
  202.           }
  203.         pos1 = ftell(original);
  204.         pos1 = ftell(save);
  205.         fread(&x,1,sizeof(int),original);
  206.         y = x;
  207.         if (p->l_symndx ==0)
  208.           { 
  209.             int w =  *((int *)&__start);
  210.             x = ((*(int *)(data_begin+off)));
  211.             x = x + header.text_start ;
  212.             x = x - w ;
  213.           }
  214.         if  (p->l_symndx ==1 || p->l_symndx ==2)
  215.           {
  216.             x = ((*(int *)(data_begin + off)) - (int) data_begin);
  217.           }
  218.         fwrite(&x,1,sizeof(int),save);
  219.         off += sizeof(int);
  220.           }
  221.       fseek(save,j1,0);
  222.       fseek(original,j2,0);
  223.  
  224.     }
  225.       }
  226.  
  227.       sbrk(- (shdrs[header.o_snloader].s_size+ 0x2000));
  228.       filecpy(save,original,Eheader.f_symptr - ftell(save));
  229.       /* now at the beginning of the sym table */
  230.       {
  231.     struct syment symbol;
  232.     struct syment *sym = &symbol;
  233.     int naux;
  234.     int nsyms = Eheader.f_nsyms;
  235.     while (--nsyms >= 0)
  236.       {
  237.         fread(&symbol,1,SYMESZ,original);
  238.         fwrite(&symbol,1,SYMESZ,save);
  239.         naux= sym->n_numaux;
  240.         nsyms = nsyms - naux;
  241.         if (ISFCN(sym->n_type)
  242.         && (naux >= 2))
  243.           { 
  244.         fread(&symbol,1,SYMESZ,original);
  245.         (((union auxent *)(sym))->x_sym.x_fcnary.x_fcn.x_lnnoptr) += diff;
  246.         fwrite(&symbol,1,SYMESZ,save);
  247.         filecpy(save,original,SYMESZ*(naux -1));
  248.           }
  249.         else
  250.           filecpy(save,original,SYMESZ*(naux));
  251.       }
  252.       }
  253.  
  254.  
  255.       COPY_TO_SAVE;
  256.       fclose(original);
  257.       fclose(save);
  258.     }
  259.   }
  260. Lsave()
  261. {
  262.     char filename[256];
  263.     check_arg(1);
  264.     check_type_or_pathname_string_symbol_stream(&vs_base[0]);
  265.     coerce_to_filename(vs_base[0], filename);
  266.     _cleanup();
  267.     /*
  268.     {
  269.         FILE *p;
  270.         int nfile;
  271.         nfile = NUMBER_OPEN_FILES;
  272.         for (p = &_iob[3];  p < &_iob[nfile];  p++)
  273.             fclose(p);
  274.     }
  275. */
  276.     memory_save(kcl_self, filename);
  277.     _exit(0);
  278.     /*
  279.     exit(0);
  280. */
  281.     /*  no return  */
  282. }
  283.  
  284.